home *** CD-ROM | disk | FTP | other *** search
/ Greenhouse Effect Detection Expriment / NASA Greenhouse Effect Detection Expriment 1992 - Disc 2.iso / software / dos / cdf22pc / src / tools / cdfwalk2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-12  |  36.6 KB  |  1,497 lines

  1. /******************************************************************************
  2. *
  3. *  NSSDC/CDF                        CDFwalk.  Part 2 of 2.
  4. *
  5. *  Version 1.0, 3-Mar-92, ST Systems (STX)
  6. *
  7. *  Modification history:
  8. *
  9. *   V1.0  25-Jul-91, H Leckner    Original version.
  10. *
  11. ******************************************************************************/
  12.  
  13. #include "wfl.h"
  14.  
  15. #include <stdio.h>
  16. #include <math.h>
  17. #include <string.h>
  18. #include <ctype.h>
  19.  
  20. #if defined(unix)
  21. #include <sys/types.h>
  22. #include <sys/stat.h>
  23. extern char *getenv();
  24. #else
  25. #if defined (vms)
  26. #include <descrip.h>
  27. #else
  28. #if defined(__MSDOS__)
  29. #include <dos.h>
  30. #endif
  31. #endif
  32. #endif
  33.  
  34. #include "cdfdist.h"
  35. #include "kb_def.h"
  36. #include "utility.h"
  37. #include "cdfwalk.h"
  38.  
  39. void CDFWALK_load_discrete(values, num_values, num_bytes, DIS_display,
  40.             num_rows, num_cols)
  41. char            values[];
  42. long int        num_values;
  43. long int        num_bytes;
  44. struct vid_struct      *DIS_display;
  45. int            *num_rows;
  46. int            *num_cols;
  47. {
  48. /*long int        temp_rows;*/
  49. long int        i;
  50. for (i=0; i<num_values; i++)
  51.      {
  52.     DIS_display[i].row = 1;
  53.     DIS_display[i].col = 1;
  54.     strcpy(DIS_display[i].label,&values[i*num_bytes]);
  55.      }
  56.  
  57. *num_rows = num_values+ROW_OFFSET > DIS_ROWS ? DIS_ROWS : num_values+ROW_OFFSET;
  58.  
  59. *num_cols = num_bytes+COL_OFFSET-1 < DIS_COLUMNS ? num_bytes+COL_OFFSET-1 : DIS_COLUMNS;
  60. }
  61. void CDFWALK_get_EPOCH(CDF_id, var_num, max_record_num,
  62.             bin_values, char_values)
  63. long int        CDF_id;
  64. long int        var_num;
  65. long int        max_record_num;
  66. double            bin_values[];
  67. char            *char_values;
  68. {
  69. long int        indices[CDF_MAX_DIMS];
  70. long int        counts[CDF_MAX_DIMS];
  71. long int        intervals[CDF_MAX_DIMS];
  72. long int        record_num;
  73. long int        recInterval;
  74. long int        i;
  75. CDFstatus        rcode;
  76. extern char        *epochString();
  77.  
  78. for (i=0; i < CDF_MAX_DIMS; i++)
  79.      {
  80.      indices[i] = 0;
  81.      counts[i] = 1;
  82.      intervals[i] = 1;
  83.      }
  84. record_num = 0;
  85. recInterval = 1;
  86. rcode = CDFvarHyperGet(CDF_id, var_num, record_num, max_record_num+1,
  87.         recInterval, indices, counts, intervals, bin_values);
  88. if(rcode == CDF_OK)
  89.    {
  90.    for (record_num=0; record_num <= max_record_num; record_num++)
  91.      {
  92.      ep.tSince0 = bin_values[record_num];
  93.      strcpy(&char_values[record_num*EPOCH_WIDTH], epochString(&ep));
  94.      }
  95.    }
  96. }
  97. void CDFWALK_get_discrete(CDF_id, dim_num, var_id, data_type, num_values,
  98.           bin_values, char_values)
  99. long int        CDF_id;
  100. long int        dim_num;
  101. long int        var_id;
  102. long int        data_type;
  103. long int        num_values;
  104. double            bin_values[];
  105. char            *char_values;
  106. {
  107. long int        indices[10];
  108. char            temp_val[MINMAX_SIZE+1];
  109. long int        i;
  110. /*long int        len;*/
  111. long int        record_num;
  112. CDFstatus        rcode;
  113. union     mixed         temp;
  114. double            r4_r8();
  115.  
  116. record_num = 0;
  117. for (i=0; i < 10; i++)
  118.      indices[i] = 0;
  119. for (i=0; i < num_values; i++)
  120.      {
  121.      if(dim_num > 0)
  122.     indices[dim_num-1]=i;
  123.      else
  124.     record_num = i;
  125.      switch(data_type)
  126.     {
  127.     case CDF_REAL4:
  128.     case CDF_FLOAT:
  129.          rcode = CDFvarGet(CDF_id, var_id, record_num,
  130.          indices, &temp.r4);
  131.          bin_values[i] = r4_r8(&temp.r4);
  132.          if(bin_values[i] < -1.e12 ||
  133.         bin_values[i] >  1.e12)
  134.         sprintf(temp_val,"%e",bin_values[i]);
  135.          else
  136.         sprintf(temp_val,"%f",bin_values[i]);
  137.          break;
  138.     case CDF_REAL8:
  139.     case CDF_DOUBLE:
  140.     case CDF_EPOCH:
  141.          rcode = CDFvarGet(CDF_id, var_id, record_num,
  142.          indices, &temp.r8);
  143.          if(temp.r8 < -1.e12 ||
  144.         temp.r8 >  1.e12)
  145.         sprintf(temp_val,"%e",temp.r8);
  146.          else
  147.         sprintf(temp_val,"%f",temp.r8);
  148.          bin_values[i] = temp.r8;
  149.          break;
  150.     case CDF_INT4:
  151.          rcode = CDFvarGet(CDF_id, var_id, record_num,
  152.          indices, &temp.i4);
  153.          sprintf(temp_val,"%ld",temp.i4);
  154.          bin_values[i] = (double) temp.i4;
  155.          break;
  156.     case CDF_UINT4:
  157.          rcode = CDFvarGet(CDF_id, var_id, record_num,
  158.          indices, &temp.ui4);
  159.          sprintf(temp_val,"%lu",temp.ui4);
  160.          bin_values[i] = (double) temp.ui4;
  161.          break;
  162.     case CDF_INT2:
  163.          rcode = CDFvarGet(CDF_id, var_id, record_num,
  164.          indices, &temp.i2);
  165.          sprintf(temp_val,"%d",temp.i2);
  166.          bin_values[i] = (double) temp.i2;
  167.          break;
  168.     case CDF_UINT2:
  169.          CDFvarGet(CDF_id, var_id, record_num,
  170.          indices, &temp.ui2);
  171.          sprintf(temp_val,"%u",temp.ui2);
  172.          bin_values[i] = (double) temp.ui2;
  173.          break;
  174.     case CDF_BYTE:
  175.     case CDF_INT1:
  176.          rcode = CDFvarGet(CDF_id, var_id, record_num,
  177.          indices, &temp.byte);
  178.          sprintf(temp_val,"%d",temp.byte);
  179.          bin_values[i] = (double) temp.byte;
  180.          break;
  181.     case CDF_UINT1:
  182.          rcode = CDFvarGet(CDF_id, var_id, record_num,
  183.          indices, &temp.ubyte);
  184.          sprintf(temp_val,"%u",temp.ubyte);
  185.          bin_values[i] = (double) temp.ubyte;
  186.     }
  187.        if(rcode == CDF_OK)
  188.       {
  189.       temp_val[MINMAX_SIZE-1] = '\0';
  190.       zero_replace(temp_val);
  191.       strcpy(&char_values[i*MINMAX_SIZE], temp_val);
  192.       }
  193.      }
  194. }
  195. void CDFWALK_get_discrete_char(CDF_id, dim_num, var_num, num_values,
  196.         num_bytes, char_values)
  197. long int        CDF_id;
  198. long int        dim_num;
  199. long int        var_num;
  200. long int        num_values;
  201. long int        num_bytes;
  202. char            *char_values;
  203. {
  204. char            *temp;
  205. long int        indices[10];
  206. long int        i;
  207. long int        record_num;
  208. CDFstatus        rcode;
  209. temp = (char *) malloc(num_bytes+1);
  210. record_num = 0;
  211. for (i=0; i < 10; i++)
  212.      indices[i] = 0;
  213. for (i=0; i < num_values; i++)
  214.      {
  215.      indices[dim_num-1] = i;
  216.      rcode = CDFvarGet(CDF_id, var_num, record_num, indices, temp);
  217.      if(rcode == CDF_OK)strcpy(&char_values[i*(num_bytes+1)], temp);
  218.      }
  219. free (temp);
  220. }
  221. void CDFWALK_clear_row(vid, display, start_elem, end_elem, end_col)
  222. WINDOWid         vid;
  223. struct    vid_struct    display[];
  224. int            start_elem;
  225. int            end_elem;
  226. int            end_col;
  227. {
  228. long int        i;
  229. int            len;
  230.  
  231. int            row, col;
  232.  
  233. for (i=start_elem; i<=end_elem; i++)
  234.      {
  235.      len = strlen(display[i-1].label);
  236.      row = display[i-1].row;
  237.      col = display[i-1].col + len;
  238.      erase_display(vid, row, col, row, end_col);
  239.      }
  240. }
  241. void CDFWALK_help(screen)
  242. struct        GLOBAL_struct    *screen;
  243. {
  244. long int         dummy;
  245. struct vid_struct      *HELP_display;
  246. long int        help_num_elements = 0;
  247. long int        i, len;
  248. int            tcode;
  249. static char        help_mes[] = "Press Return key when done";
  250. static char        help_error_mes[] = "Help not available ";
  251. static char        help_error_mal[] = "Help not available, malloc error ";
  252. char            key_line1[KEY_COLUMNS-COL_OFFSET+1]; /* V1.5 */
  253. char                   key_line2[KEY_COLUMNS-COL_OFFSET+1]; /* V1.5 */
  254. char            temp[80];
  255. int            help_rows, help_columns, paste_col;
  256. int            max_len;
  257. static            first = TRUE;
  258. if(HELP_ptr != NULL)
  259.    {
  260. /*
  261. READ text until complete and load into a vid structure
  262. */
  263.    max_len = 0;
  264.    fseek(HELP_ptr, 0l, SEEK_SET);
  265.    while (fgets(temp,80,HELP_ptr) != NULL)
  266.       {
  267.       help_num_elements++;
  268.       len = lastc(temp);
  269.       if(len > max_len)max_len = len;
  270.       }
  271.    if(help_num_elements > HELP_ROWS)
  272.       help_rows = HELP_ROWS;
  273.    else
  274.       help_rows = help_num_elements+ROW_OFFSET;
  275.  
  276.    if(max_len > HELP_COLUMNS)
  277.       help_columns = HELP_COLUMNS;
  278.    else
  279.       help_columns = max_len+COL_OFFSET;
  280.  
  281.    paste_col = (80-help_columns)/2+1;
  282.  
  283.    if(first)
  284.       create_virtual_display(help_rows, help_columns, &S.HELP_vid, BORDER, BOLD);
  285.    first = FALSE;
  286.  
  287.    HELP_display = (struct vid_struct *)
  288.           malloc(help_num_elements * sizeof(struct vid_struct));
  289.    if(HELP_display == NULL)
  290.       {
  291.       CDFWALK_put_message(S.MES_vid, help_error_mal, RINGBELL, NORMAL,
  292.         NOPAUSE);
  293.       return;
  294.       }
  295.    fseek(HELP_ptr, 0l, SEEK_SET);
  296.    i=0;
  297.    for(i=0; i <help_num_elements; i++)
  298.     {
  299.     fgets(temp,80,HELP_ptr);
  300.     HELP_display[i].row = 1;
  301.     HELP_display[i].col = 1;
  302.     len = lastc(temp) - 1;
  303.     strncpy(HELP_display[i].label,temp,len);
  304.     HELP_display[i].label[len] = '\0';
  305.     }
  306. /*
  307. LOAD in the keypad definitions for this option
  308. */
  309.     key_line1[0] = '\0'; key_line2[0] = '\0';
  310.     strcat(key_line1, UP); strcat(key_line1,PUP);
  311.     strcat(key_line2, DOWN);strcat(key_line2,PDOWN);
  312.     strcat(key_line2,CNTRLW);
  313.     CDFWALK_load_keydef(S.KEY_vid, key_line1, key_line2);
  314.     CDFWALK_put_message(S.MES_vid, help_mes, NOBELL, NORMAL, NOPAUSE);
  315. /*
  316. Display the HELP screen
  317. */
  318.     CDFWALK_select_menu_item(S.HELP_vid, S.MES_vid,
  319.     &dummy, HELP_display, help_num_elements, help_rows, help_columns,
  320.     HELP_ROW_PASTE, paste_col, HELP_MENU, &tcode);
  321.     free(HELP_display);
  322.    }
  323. else
  324.    CDFWALK_put_message(S.MES_vid, help_error_mes, RINGBELL, NORMAL, NOPAUSE);
  325. }
  326. int lastc(buf)
  327. char    *buf;
  328. {
  329. int done = FALSE;
  330. int i,j;
  331. int end;
  332. i = strlen(buf) + 1;
  333. end = i;
  334. j = 0;
  335. while(j < end && !done)
  336.       {
  337.       if(!isgraph(buf[i-1]))
  338.      done = TRUE;
  339.       else
  340.      j++; i--;
  341.       }
  342. return(i);
  343. }
  344.  
  345. void CDFWALK_field_menu(screen, option)
  346. struct        GLOBAL_struct    *screen;
  347. long int    *option;
  348. {
  349. int        tcode, cont;
  350. long int    temp;
  351. /*char        key_line1[KEY_COLUMNS-COL_OFFSET+1];*/
  352. /*char               key_line2[KEY_COLUMNS-COL_OFFSET+1];*/
  353. /*long int    flag;*/
  354. temp = *option+1;
  355. cont = CONTINUE;
  356. while(cont != DONE)
  357.       {
  358. /*
  359. Choose the particular field you wish to be in
  360. */
  361.       CDFWALK_Menu_keydef(screen);
  362.       CDFWALK_select_menu_item(S.FIELD_vid, S.MES_vid, &temp,
  363.       FIELD_display, FIELD_NUM_ELEMENTS, FIELD_ROWS, FIELD_COLUMNS,
  364.       FIELD_ROW_PASTE, FIELD_COL_PASTE, MENU, &tcode);
  365.       *option = temp-1;
  366.       if(*option == HELP_FIELD)
  367.      CDFWALK_help(screen);
  368.       else
  369.      cont = DONE;
  370.        }
  371. }
  372.  
  373. void CDFWALK_open_screen(screen)
  374. struct    GLOBAL_struct    *screen;
  375. {
  376. create_pasteboard();
  377. #if defined(vms)
  378. begin_pasteboard_update();
  379. #endif
  380. create_virtual_display(CDF_ROWS, CDF_COLUMNS, &S.CDF_vid, BORDER, BOLD);
  381. paste_virtual_display(S.CDF_vid, CDF_ROW_PASTE, CDF_COL_PASTE);
  382. #if defined(unix)
  383. begin_display_update(S.CDF_vid);
  384. #endif
  385. load_vid(S.CDF_vid, CDF_display, 0, CDF_NUM_ELEMENTS-1, NO_label);
  386. #if defined(unix)
  387. end_display_update(S.CDF_vid);
  388. #endif
  389. create_virtual_display(VAR_ROWS, VAR_COLUMNS, &S.VAR_vid, BORDER, BOLD);
  390. paste_virtual_display(S.VAR_vid, VAR_ROW_PASTE, VAR_COL_PASTE);
  391. create_virtual_display(KEY_ROWS, KEY_COLUMNS, &S.KEY_vid, BORDER, BOLD);
  392. paste_virtual_display(S.KEY_vid, KEY_ROW_PASTE, MES_COL_PASTE);
  393. create_virtual_display(MES_ROWS, MES_COLUMNS, &S.MES_vid, BORDER, BOLD);
  394. paste_virtual_display(S.MES_vid, MES_ROW_PASTE, MES_COL_PASTE);
  395. create_virtual_display(VARSCROLL_ROWS, VARSCROLL_COLUMNS, &S.VARSCROLL_vid,
  396.             BORDER, BOLD);
  397. create_virtual_display(FIELD_ROWS, FIELD_COLUMNS, &S.FIELD_vid,
  398. BORDER, BOLD);
  399. create_virtual_display(DIS_ROWS, DIS_COLUMNS, &S.DIS_vid, BORDER, BOLD);
  400. create_virtual_display(DIM_ROWS, DIM_COLUMNS, &S.DIM_vid, BORDER, BOLD);
  401. create_virtual_display(DIR_ROWS, DIR_COLUMNS, &S.DIR_vid, BORDER, BOLD);
  402.  
  403. #if defined(vms)
  404. end_pasteboard_update();
  405. enable_trap(S.MES_vid);
  406. #endif
  407. load_vid(S.KEY_vid, KEY_display, 0, KEY_NUM_ELEMENTS, KEY_label);
  408. load_vid(S.MES_vid, MES_display, 0, MES_NUM_ELEMENTS, MES_label);
  409. }
  410. #if defined(unix) | defined(ultrix) | defined(__MSDOS__)
  411. void CDFWALK_draw_main_screen(screen, WALK, EPOCH)
  412. struct    GLOBAL_struct    *screen;
  413. long int        WALK;
  414. long int        EPOCH;
  415. {
  416. repaste_virtual_display(S.CDF_vid, CDF_ROW_PASTE, CDF_COL_PASTE);
  417. repaste_virtual_display(S.VAR_vid, VAR_ROW_PASTE, VAR_COL_PASTE);
  418. repaste_virtual_display(S.KEY_vid, KEY_ROW_PASTE, KEY_COL_PASTE);
  419. label_border(S.KEY_vid, KEY_label, strlen(KEY_label));
  420. repaste_virtual_display(S.MES_vid, MES_ROW_PASTE, MES_COL_PASTE);
  421. label_border(S.MES_vid, MES_label, strlen(MES_label));
  422. if(WALK)
  423.    {
  424.    repaste_virtual_display(S.WALK_vid, WALK_ROW_PASTE, WALK_COL_PASTE);
  425.    if(!EPOCH)
  426.       label_border(S.WALK_vid, WALK_label,strlen(WALK_label));
  427.    else
  428.       label_border(S.WALK_vid, WALK_EPOCH_label, strlen(WALK_EPOCH_label));
  429.   }
  430. }
  431. #endif
  432. void CDFWALK_select_menu_item(vid, MES_vid, rvalue, display,
  433. num_elements, num_rows, num_columns, row_start, col_start, mode, termcode)
  434. WINDOWid    vid;
  435. WINDOWid    MES_vid;
  436. long int     *rvalue;
  437. struct        vid_struct    display[];
  438. int        num_elements;
  439. int        num_rows;
  440. int        num_columns;
  441. int        row_start;
  442. int        col_start;
  443. int        mode;
  444. int        *termcode;
  445. {
  446. int        in_value;
  447. int        row, col;
  448. int        tcode;
  449. int        done;
  450. int        num_screen;
  451. int        start_page;
  452. int        end;
  453. int        value;
  454. int        row1 = 1;
  455. int        col1 = 1;
  456. static char    top[]    = "Top of menu";
  457. static char    bottom[] = "Bottom of menu";
  458.  
  459. in_value = *rvalue;
  460. /*
  461. Find out the number of rows to be on the screen at one time
  462. */
  463. num_rows = num_rows - ROW_OFFSET;
  464. num_columns = num_columns - COL_OFFSET;
  465. if(num_elements > num_rows)
  466.    num_screen = num_rows;
  467. else
  468.    num_screen = num_elements;
  469. /*
  470. Erase and load data into the menu for selection
  471. */
  472. value = 1;
  473. row = 1;
  474. col = 1;
  475. #if defined(unix) | defined(ultrix) | defined(__MSDOS__)
  476. begin_display_update(vid);
  477. #endif
  478. erase_display(vid, 1, 1, num_rows, num_columns);
  479. load_menu(vid, display, num_screen, NO_label);
  480. change_rendition(vid,1,1,num_rows,num_columns,NORMAL);
  481. paste_virtual_display(vid, row_start, col_start);
  482. #if defined(unix) | defined(ultrix) | defined(__MSDOS__)
  483. end_display_update(vid);
  484. #endif
  485. start_page = 1;
  486. if(mode == MENU)change_rendition(vid, row, col, 1, num_columns, REVERSE);
  487. done = FALSE;
  488. while(!done)
  489.      {
  490.      set_cursor_abs(vid, row, col);
  491. #ifdef vms
  492.      read_input(&tcode);
  493. #endif
  494. #if defined(unix) | defined(ultrix) | defined(__MSDOS__)
  495.      read_input(vid, &tcode);
  496. #endif
  497.      switch (tcode)
  498.       {
  499.       case KB_DOWNARROW:
  500.            if(row == num_rows || value == num_elements)
  501.           if(value < num_elements)
  502.              {
  503. /*
  504. SCROLL UP
  505. */
  506.              value++; start_page++;
  507.              begin_display_update(vid);
  508.              erase_display(vid, row1, col1, num_rows, num_columns);
  509.              load_menu(vid, display+(start_page-1),
  510.              num_screen, NO_label);
  511.              end_display_update(vid);
  512.              }
  513.           else
  514.              {
  515.              value = 1;
  516.              row = 1;
  517.              start_page = 1;
  518.              begin_display_update(vid);
  519.              erase_display(vid, 1, 1, num_rows, num_columns);
  520.              load_menu(vid, display, num_screen, NO_label);
  521.              end_display_update(vid);
  522.              }
  523.            else
  524.           {
  525.           row++; value++;
  526.           }
  527.            break;
  528.       case KB_UPARROW:
  529.            if(row > 1)
  530.           {
  531.              row--;
  532.              value--;
  533.           }
  534.            else if(value > 1)
  535.           {
  536. /*
  537. SCROLL DOWN
  538. */
  539.              value--; start_page--;
  540.              begin_display_update(vid);
  541.              erase_display(vid, row1, col1, num_rows, num_columns);
  542.              load_menu(vid, display+(start_page-1),
  543.              num_screen, NO_label);
  544.              end_display_update(vid);
  545.           }
  546.            else
  547.           {
  548.              start_page = num_elements - num_screen + 1;
  549.              value = num_elements;
  550.              row = num_screen;
  551.              begin_display_update(vid);
  552.              erase_display(vid, row1, col1, num_rows, num_columns);
  553.              load_menu(vid, display+(start_page-1),
  554.              num_screen, NO_label);
  555.              end_display_update(vid);
  556.           }
  557.            break;
  558. /*
  559. PAGE DOWN
  560. */
  561.       case PAGEdown:
  562.       case PAGEDOWN:
  563.            start_page = start_page + num_screen;
  564.            end = start_page + num_screen - 1;
  565.            value = value + num_screen;
  566.            if(end > num_elements)
  567.           {
  568. /*
  569. Display the next page down
  570. */
  571.           end = num_elements;
  572.           start_page = end - num_screen + 1;
  573.           value = num_elements;
  574.           row = num_rows;
  575.           CDFWALK_put_message(MES_vid, bottom, NOBELL, NORMAL, NOPAUSE);
  576.           }
  577.            begin_display_update(vid);
  578.            erase_display(vid, row1, col1, num_rows, num_columns);
  579.            load_menu(vid, display+(start_page-1), num_screen, NO_label);
  580.            end_display_update(vid);
  581.            break;
  582. /*
  583. PAGE UP
  584. */
  585.       case PAGEUP:
  586.       case PAGEup:
  587.            start_page = start_page - num_screen;
  588.            value = value - num_screen;
  589.            if(start_page < 1)
  590.           {
  591.           start_page = 1;
  592.           value = 1;
  593.           row = 1;
  594.           CDFWALK_put_message(MES_vid, top, NOBELL, NORMAL, NOPAUSE);
  595.           }
  596.            begin_display_update(vid);
  597. /*
  598. Display the next page up
  599. */
  600.            erase_display(vid, row1, col1, num_rows, num_columns);
  601.            load_menu(vid, display+(start_page-1), num_screen, NO_label);
  602.            end_display_update(vid);
  603.            break;
  604.       case KB_RETURN:
  605.       case KB_PAD_ENTER:
  606.            done = TRUE;
  607.            *rvalue = value;
  608.            *termcode = KB_RETURN;
  609.            break;
  610.       case QUIT:
  611.       case quit:
  612.            done = TRUE;
  613.            *rvalue = in_value;
  614.            *termcode = QUIT;
  615.            break;
  616.       case KB_CTRL_F:
  617.            done = TRUE;
  618.            *rvalue = value;
  619.            *termcode = KB_CTRL_F;
  620.            break;
  621.       case KB_REDRAW:
  622.            repaint_screen();
  623.            break;
  624.       default:
  625.         break;
  626.       }
  627.       if(mode == MENU)
  628.          {
  629.          change_rendition(vid, 1, 1, num_rows, num_columns, NORMAL);
  630.          change_rendition(vid, row, 1, 1, num_columns, REVERSE);
  631.          }
  632.       }
  633. unpaste_virtual_display(vid);
  634. }
  635. int CDFWALK_CDF_name(screen, CDF, field_num, input_type)
  636. struct    GLOBAL_struct    *screen;
  637. struct    CDF_struct    *CDF;
  638. long int        *field_num;
  639. long int        *input_type;
  640. {
  641. char            file_spec[256],temp[256] /*, dummy[256]*/ ;
  642. static char        save[CDF_PATHNAME_LEN];
  643. char            save_name[CDF_PATHNAME_LEN];
  644. char            save_temp[CDF_PATHNAME_LEN];
  645. char             **directory_list;
  646. char            **result_spec_list;
  647. int            num_files = 0;
  648. int            termcode, /*cont,*/ i, row;
  649. int            drows;
  650. long int        CDF_num;
  651. int            tcode;
  652. int            done;
  653. int             dir;
  654. static int        first = TRUE;
  655. char            row_data[CDF_COLUMNS];
  656. #if defined(unix)
  657. static char curr_dir[] = "./*.cdf" ;
  658. #else
  659. #if defined(__MSDOS__)
  660. static char curr_dir[] = ".\\*.cdf";
  661. #else
  662. #if defined(vms)
  663. static char curr_dir[] = "[]*.cdf";
  664. #endif
  665. #endif
  666. #endif
  667.  
  668. static char dir_mes[] =
  669. "Enter Directory and/or CDF name (default=CDFs in current directory)";
  670. static char dir_error[] = "No CDFs found, reenter directory and/or CDF name";
  671. static char select_mes[] =
  672. "Select a CDF or press Q to enter a new Directory/CDF_name";
  673. struct vid_struct      *DIR_display;
  674. char            key_line1[KEY_COLUMNS-COL_OFFSET+1];    /* V1.5 */
  675. char                   key_line2[KEY_COLUMNS-COL_OFFSET+1];    /* V1.5 */
  676. int            new_CDF;
  677. int             regfile;
  678. int            last_error = FALSE;
  679. strcpy(save_name, C.CDF_name);
  680. new_CDF= FALSE;
  681. done = FALSE;
  682. regfile = FALSE;
  683. while(!done)
  684. {
  685. if(*input_type == MANUAL)
  686.    {
  687.    if(first)
  688.       {
  689.       key_line1[0] = '\0'; key_line2[0] = '\0';
  690.       strcat(key_line1, CNTRLM); strcat(key_line1, RET);strcat(key_line1, CNTRLN);
  691.       strcat(key_line2, CNTRLW);strcat(key_line2, HLP);
  692.       strcat(key_line2, "  ");strcat(key_line2, CNTRLD);        /* V1.5 */
  693.       CDFWALK_load_keydef(S.KEY_vid, key_line1, key_line2);
  694.       if(!last_error)
  695.      {
  696.      for (i=0; i < CDF_NAME_LENGTH; i++)
  697.           C.CDF_name[i] = '\0';
  698.      strcpy(C.CDF_name, default_name);
  699.  
  700.      CDFWALK_put_selection(S.CDF_vid, CDF_display, 0,
  701.           C.CDF_name, CDF_NAME_LENGTH-COL_OFFSET, REVERSE);
  702.      }
  703.       CDFWALK_put_message(S.MES_vid, dir_mes, NOBELL, NORMAL, NOPAUSE);
  704.       input_field(S.CDF_vid, C.CDF_name,
  705.       CDF_NAME_ROW, CDF_NAME_COL, CDF_NAME_LENGTH-COL_OFFSET, &termcode);
  706.       }
  707.    else
  708.       CDFWALK_put_selection(S.CDF_vid, CDF_display, 0,
  709.           save, CDF_NAME_LENGTH-COL_OFFSET, REVERSE);
  710.    }
  711. else
  712.     termcode = KB_RETURN;
  713. *input_type = MANUAL;
  714. first = FALSE;
  715. last_error = FALSE;
  716. CDFWALK_clear_row(S.MES_vid, MES_display, 1, 1, MES_COLUMNS-COL_OFFSET);
  717. if(termcode == KB_CTRL_F)
  718.    {
  719.    CDFWALK_field_menu(screen, field_num);
  720.    if((int) (*field_num) != CDF_FIELD)
  721.       {
  722.       done = TRUE;
  723.       tcode = QUIT;
  724.       }
  725.    else
  726.       first = TRUE;
  727.    }
  728. else
  729.    {
  730.    row = CDF_NAME_ROW;
  731.  
  732.    read_display(S.CDF_vid, row, row_data);
  733.  
  734.    for (i=CDF_NAME_COL; i < CDF_NAME_COL+CDF_NAME_LENGTH-1; i++)
  735.     if(row_data[i-1] != 32)
  736.        temp[i-CDF_NAME_COL] = row_data[i-1];
  737.     else
  738.        temp[i-CDF_NAME_COL] = '\0';
  739. /*
  740. Save for next time
  741. */
  742.    strcpy(save_temp, temp);
  743.  
  744.    strcpy(file_spec, temp);
  745.    if(strlen(file_spec) == 0)
  746.       strcpy(file_spec, curr_dir);
  747.    else
  748.       {
  749.       dir = FALSE;
  750.       strcpy(temp, file_spec);
  751.       strcat(temp,".cdf");
  752.       if(!IsReg(temp))
  753.       {
  754.       regfile = FALSE;
  755.       if(IsDir(file_spec))
  756.           {
  757.           AppendToDir(file_spec, "*.cdf");
  758.           dir = TRUE;
  759.           }
  760.       else
  761.           strcat(file_spec, ".cdf");
  762.       }/* end else */
  763.       else
  764.       {
  765.       regfile = TRUE;
  766.       strcat(file_spec, ".cdf");
  767.       }
  768.       }/* end else */
  769.    num_files = DirList(file_spec, &directory_list, &result_spec_list);
  770.    if(num_files > 0)
  771.       {
  772.       strcpy(save, save_temp);
  773.       RemoveExtensions(num_files, result_spec_list);
  774.       done = TRUE;
  775.       if(num_files == 1 && regfile)
  776.      {
  777.      CDF_num = 1;
  778.      tcode = KB_RETURN;
  779.      first = TRUE;
  780.      }
  781.        else
  782.      {
  783. /*
  784. allocate the space for a vid structure which contains the CDF NAMES
  785. */
  786.      DIR_display = (struct vid_struct *)
  787.            malloc(num_files * sizeof(struct vid_struct));
  788.      if(DIR_display == NULL)return(BAD_MALLOC);
  789. /*
  790. Load in the cdf names into the structure
  791. */
  792.      for (i=0; i<num_files; i++)
  793.        {
  794.        DIR_display[i].row = 1;
  795.        DIR_display[i].col = 1;
  796.        strcpy(DIR_display[i].label, result_spec_list[i]);
  797.        }
  798.      if((num_files+ROW_OFFSET) > DIR_ROWS)
  799.          drows = DIR_ROWS;
  800.      else
  801.          drows = num_files + ROW_OFFSET;
  802. #if defined(vms)
  803.      change_virtual_display(drows, DIR_COLUMNS, S.DIR_vid,
  804.                   BORDER, BOLD);
  805. #else
  806.      change_virtual_display(drows, DIR_COLUMNS, &S.DIR_vid,
  807.                   BORDER, BOLD);
  808. #endif
  809.      CDFWALK_put_message(S.MES_vid, select_mes, NOBELL, NORMAL, NOPAUSE);
  810.      CDFWALK_Menu_keydef(screen);
  811.      CDFWALK_select_menu_item(S.DIR_vid,
  812.        S.MES_vid, &CDF_num, DIR_display, num_files, drows,
  813.        DIR_COLUMNS, DIR_ROW_PASTE, DIR_COL_PASTE, MENU, &tcode);
  814.      free (DIR_display);
  815.      } /* end num_files > 1 */
  816.      if(tcode == KB_RETURN)
  817.           {
  818.           if(dir || strlen(directory_list[CDF_num-1]) > 0)
  819.          {
  820.          strcpy(C.CDF_name, directory_list[CDF_num-1]);
  821.          AppendToDir(C.CDF_name, result_spec_list[CDF_num-1]);
  822.          }
  823.           else
  824.          strcpy(C.CDF_name, result_spec_list[CDF_num-1]);
  825.  
  826.           C.CDF_name[CDF_NAME_LENGTH]= '\0';
  827.           CDFWALK_put_selection(S.CDF_vid, CDF_display, 0,
  828.           C.CDF_name, CDF_NAME_LENGTH-COL_OFFSET, REVERSE);
  829.           new_CDF = TRUE;
  830.           *field_num = WALK_FIELD;
  831.           }
  832.        else
  833.           {
  834.           change_rendition(S.CDF_vid, CDF_NAME_ROW, CDF_NAME_COL, 1,
  835.           strlen(C.CDF_name), REVERSE);
  836.           if(tcode == KB_CTRL_F)
  837.          {
  838.          CDFWALK_field_menu(screen, field_num);
  839.          if((int) (*field_num) == CDF_FIELD)done = FALSE;
  840.          }
  841.           else
  842.          done = FALSE;
  843.           first = TRUE;
  844.       } /* num > 1 */
  845.  
  846.       free (directory_list);
  847.       free (result_spec_list);
  848.        } /*num_file > 0*/
  849.        else
  850.        {
  851.        CDFWALK_put_message(S.MES_vid, dir_error, RINGBELL, NORMAL, PAUSE);
  852.        first = TRUE;
  853.        last_error = TRUE;
  854.        }
  855.    }/*keyboard != C-F*/
  856. }/*done?*/
  857. /*
  858. If a new CDF was not selected put the old one back on the input line
  859. */
  860. if(!new_CDF)
  861.    {
  862.    strcpy(C.CDF_name, save_name);
  863.    CDFWALK_put_selection(S.CDF_vid, CDF_display, 0,
  864.           C.CDF_name, CDF_NAME_LENGTH-COL_OFFSET, REVERSE);
  865.    }
  866. return(tcode);
  867.  
  868. }
  869. void CDFWALK_CDF_info(screen, CDF, CDF_display)
  870. struct    GLOBAL_struct    *screen;
  871. struct    CDF_struct    *CDF;
  872. struct  vid_struct    CDF_display[];
  873. {
  874. char         string[21];
  875. char        temp[7];
  876. long int    i;
  877. sprintf(string, "%ld ", C.num_vars);
  878. CDFWALK_clear_row(S.CDF_vid, CDF_display, NUMVAR_ELEMENT_NUM,
  879.             NUMVAR_ELEMENT_NUM, 27);
  880. CDFWALK_put_selection(S.CDF_vid, CDF_display, NUMVAR_ELEMENT_NUM-1, string,
  881.     6, REVERSE);
  882. sprintf(string, "%ld ", C.max_record_num+1);
  883. CDFWALK_clear_row(S.CDF_vid, CDF_display, NUMREC_ELEMENT_NUM,
  884.             NUMREC_ELEMENT_NUM, CDF_COLUMNS-COL_OFFSET);
  885. CDFWALK_put_selection(S.CDF_vid, CDF_display, NUMREC_ELEMENT_NUM-1, string,
  886.     6, REVERSE);
  887. sprintf(string, "%ld ", C.num_dims);
  888. CDFWALK_clear_row(S.CDF_vid, CDF_display, NUMDIM_ELEMENT_NUM,
  889.             NUMDIM_ELEMENT_NUM, CDF_COLUMNS-COL_OFFSET);
  890. CDFWALK_put_selection(S.CDF_vid, CDF_display, NUMDIM_ELEMENT_NUM-1, string,
  891.     2, REVERSE);
  892. string[0] = '\0';
  893. CDFWALK_clear_row(S.CDF_vid, CDF_display, DIMSIZ_ELEMENT_NUM,
  894.             DIMSIZ_ELEMENT_NUM, CDF_COLUMNS-COL_OFFSET);
  895. if(C.num_dims > 0)
  896.    {
  897.    for (i=0; i < C.num_dims; i++)
  898.     {
  899.     sprintf(temp, "%ld ", C.dim_sizes[i]);
  900.     strcat(string, temp);
  901.     }
  902.    }
  903. else
  904.     string[0] = '\0';
  905. CDFWALK_put_selection(S.CDF_vid, CDF_display, DIMSIZ_ELEMENT_NUM-1, string,
  906.     10, REVERSE);
  907. }
  908. void load_vid(vid, display, start_element, num_elements, label)
  909. WINDOWid         vid;
  910. struct    vid_struct    display[];
  911. int            start_element;
  912. int            num_elements;
  913. char            label[];
  914. {
  915. long int        i;
  916. int            len;
  917.  
  918. int        erase_mode = NOERASE;
  919. int        video_type = NORMAL;
  920. len = strlen(label);
  921. if(len > 0)label_border(vid, label, len);
  922. for(i=0; i< num_elements; i++)
  923.     {
  924.     len = strlen(display[i+start_element].label);
  925.     put_chars(vid, display[i+start_element].label, len,
  926.     display[i+start_element].row, display[i+start_element].col,
  927.     erase_mode, video_type);
  928.     }
  929. }
  930. void load_vid_element(vid, display, element_num)
  931. WINDOWid         vid;
  932. struct    vid_struct    display[];
  933. int            element_num;
  934. {
  935.  
  936. int            len;
  937.  
  938. long int        erase_mode = NOERASE;
  939. long int        video_type = NORMAL;
  940.  
  941. len = strlen(display[element_num-1].label);
  942. put_chars(vid, display[element_num-1].label, len,
  943. display[element_num-1].row, display[element_num-1].col, erase_mode, video_type);
  944. }
  945. void CDFWALK_load_keydef(vid, line1, line2)
  946. WINDOWid         vid;
  947. char            line1[];
  948. char            line2[];
  949. {
  950. int            row, col;
  951. int            erase_mode;
  952. int            video_type;
  953. int            len;
  954.  
  955. begin_display_update(vid);
  956. erase_display(vid, 1, 1, KEY_ROWS-ROW_OFFSET, KEY_COLUMNS-COL_OFFSET);
  957. row = 1; col = 1; erase_mode = ERASE; video_type = NORMAL;
  958. len = strlen(line1);
  959. if(len > (KEY_COLUMNS-COL_OFFSET))len = KEY_COLUMNS - COL_OFFSET;
  960. put_chars(vid, line1, len, row, col, erase_mode, video_type);
  961. len = strlen(line2);
  962. row = 2; col = 1; erase_mode = ERASE; video_type = NORMAL;
  963. if(len > (KEY_COLUMNS-COL_OFFSET))len = KEY_COLUMNS - COL_OFFSET;
  964. put_chars(vid, line2, len, row, col, erase_mode, video_type);
  965. #if defined(vms)
  966. end_display_update(vid);
  967. #else
  968. end_display_update_nobox(vid);
  969. #endif
  970. }
  971. void CDFWALK_put_selection(vid, display, element_num, selection,
  972.                 field_len, video_type)
  973. WINDOWid         vid;
  974. struct    vid_struct    display[];
  975. int            element_num;
  976. char            selection[];
  977. int            field_len;
  978. int            video_type;
  979. {
  980. /*long int        i;*/
  981. int            len;
  982.  
  983. int            erase_mode = NOERASE;
  984. int            row, col, end_col;
  985.  
  986. len = strlen(display[element_num].label);
  987. row = display[element_num].row;
  988. col = display[element_num].col + len;
  989. len = strlen(selection);
  990. end_col = col + field_len - 1;
  991. erase_display(vid, row, col, row, end_col);
  992. put_chars(vid, selection, len, row, col, erase_mode, video_type);
  993. }
  994. void CDFWALK_put_value(vid, display, element_num, bin_value)
  995. WINDOWid         vid;
  996. struct    vid_struct    display[];
  997. int            element_num;
  998. double            bin_value;
  999. {
  1000. char            value[20];
  1001. long int        i;
  1002. int            len;
  1003.  
  1004. int            erase_mode = NOERASE;
  1005. int            video_type = NORMAL;
  1006. int            row, col, end_col;
  1007.  
  1008. len = strlen(display[element_num].label);
  1009. row = display[element_num].row;
  1010. col = display[element_num].col;
  1011. end_col = col + 20;
  1012. erase_display(vid, row, col, row, end_col);
  1013. sprintf(value,"%f",bin_value);
  1014. zero_replace(value);
  1015. len = strlen(value);
  1016. for(i = len; i<14; i++)
  1017.     value[i] = ' ';
  1018. value[14] = '\0';
  1019. len = 14;
  1020. put_chars(vid, value, len, row, col, erase_mode, video_type);
  1021. }
  1022. void CDFWALK_put_message(vid, message, rbell, video_type, pause)
  1023. WINDOWid         vid;
  1024. char            message[];
  1025. int            rbell;
  1026. int            video_type;
  1027. int            pause;
  1028. {
  1029. /*long int        i;*/
  1030. int            len;
  1031.  
  1032. int            erase_mode = ERASE;
  1033. int            row, col;
  1034. #if defined(vms)
  1035. float            wait = 3.;
  1036. #endif
  1037.  
  1038. len = strlen(message);
  1039. row = 1;
  1040. col = 1;
  1041. if(rbell == RINGBELL)
  1042. #if defined(vms)
  1043.     ring_bell(vid);
  1044. #else
  1045.     ring_bell();
  1046. #endif
  1047. if(len > (MES_COLUMNS-COL_OFFSET))len = MES_COLUMNS - COL_OFFSET;
  1048. put_chars(vid, message, len, row, col, erase_mode, video_type);
  1049. if(pause == PAUSE)
  1050. #ifdef vms
  1051.              lib$wait(&wait);
  1052. #endif
  1053.  
  1054. #if defined(unix) | defined(ultrix) | defined(__MSDOS__)
  1055.              sleep(3);
  1056. #endif
  1057.  
  1058. }
  1059. void load_menu(vid, display, num_elements, label)
  1060. WINDOWid         vid;
  1061. struct    vid_struct    display[];
  1062. int            num_elements;
  1063. char            label[];
  1064. {
  1065. long int        i;
  1066. int            len;
  1067.  
  1068. int            erase_mode = NOERASE;
  1069. int            video_type = NORMAL;
  1070. int            row;
  1071. int            col = 1;
  1072. len = strlen(label);
  1073. if(len > 0)label_border(vid, label, len);
  1074. for(i=0; i< num_elements; i++)
  1075.     {
  1076.     row = i + 1;
  1077.     len = strlen(display[i].label);
  1078.     put_chars(vid, display[i].label, len, row, col,
  1079.     erase_mode, video_type);
  1080.     }
  1081. }
  1082. void zero_replace(string)
  1083. char        string[];
  1084. {
  1085. long int    zero_index;
  1086. /*long int    period;*/
  1087. long int    byte /*, ebyte*/ ;
  1088. long int    found = FALSE;
  1089. long int    len;
  1090.  
  1091. CDFWALK_left_justify(string);
  1092. byte = 0;
  1093. len = strlen(string);
  1094. while(byte < len && !found)
  1095.       {
  1096.       if(string[byte] == PERIOD)found = TRUE;
  1097.       byte++;
  1098.       }
  1099. if(found)
  1100.    {
  1101.    zero_index = byte;
  1102.    while(byte < len)
  1103.       {
  1104.       if(string[byte] == '0')
  1105.       {
  1106.       if(zero_index == 0)zero_index = byte;
  1107.       }
  1108.       else
  1109.      zero_index = 0;
  1110.       byte++;
  1111.       }
  1112.    if(zero_index > 0)
  1113.      {
  1114.      for (byte=zero_index; byte<len; byte++)
  1115.       string[byte] = ' ';
  1116.      }
  1117.    }
  1118. }
  1119. void CDFWALK_left_justify (field)
  1120.     char        field[];
  1121. {
  1122.     long int    i;
  1123.     long int    index;
  1124.     long int    done;
  1125.     char        *temp;
  1126.     long int    len;
  1127.     len = strlen(field);
  1128.     temp = (char *) malloc(len);
  1129.  
  1130. /* Blank out temporary hold area */
  1131.  
  1132.     for (i = 0; i < len; i++)
  1133.         temp[i] = ' ';
  1134.  
  1135.  
  1136.         done = FALSE;
  1137.         for (index = 0; done != TRUE && index <= len; index++)
  1138.  
  1139.                 {
  1140. /* Look for a non-blank character */
  1141.  
  1142.             if(field[index] != ' ')
  1143.                 {
  1144. /* Left Justify by copying from the non-blank character to the end of field */
  1145.  
  1146.                 strncpy(temp,field+index,len-index);
  1147.                 for (i = 0; i < len; i++)
  1148.                     field[i] = ' ';
  1149.  
  1150. /* Now copy from the temporary field back to the permanent field */
  1151.  
  1152.                 strncpy(field, temp, len);
  1153.                 done = TRUE;
  1154.                   }
  1155.             }
  1156. free(temp);
  1157. }
  1158. int precision(num)
  1159. double        num;
  1160. {
  1161. double        abs_value;
  1162. int        p;
  1163. abs_value = fabs(num);
  1164. if(abs_value < 1.)
  1165.     p = 5;
  1166. else if(abs_value < 10.)
  1167.     p = 4;
  1168. else if(abs_value < 10000.)
  1169.     p = 3;
  1170. else if(abs_value < 100000.)
  1171.     p = 2;
  1172. else
  1173.     p = 1;
  1174. return(p);
  1175. }
  1176. CDFstatus CDFWALK_close(CDF, variables)
  1177. struct    CDF_struct    *CDF;
  1178. struct variable_struct    *variables;
  1179. {
  1180. CDFstatus        rcode;
  1181.  
  1182. CDFWALK_free_discrete(variables, C.num_vars);
  1183. free(variables);
  1184. free(C.all_dim_var_num);
  1185. rcode = CDFclose(C.CDF_id);
  1186. return(rcode);
  1187. }
  1188. void CDFWALK_close_screen()
  1189. {
  1190. delete_pasteboard(ERASE);
  1191. }
  1192. double r4_r8(r4_ptr)
  1193. float    *r4_ptr;
  1194. {
  1195. /*
  1196. Convert float to double
  1197. Based on assumption that float contains 7 significant digits
  1198. */
  1199. float r4;
  1200. double        r4r8;
  1201. double         fracr8;
  1202. float          realexp,temp,rfrac,x;
  1203. double        base, power;
  1204. long int     /*itemp,*/ exp,frac;
  1205. long int     evalue;
  1206.  
  1207. r4 = *r4_ptr;
  1208. /*
  1209. If the REAL*4 value is 0 then just set the REAL*8 value to 0 and return
  1210. */
  1211. if(r4 == 0.) return(0.);
  1212.  
  1213. temp = r4;
  1214. evalue  = 0;
  1215. /*
  1216. Calculate the exponent of the incoming REAL*4 value
  1217. If absolute value ge 10 exponent is positive 
  1218. If absolute value lt 1  exponent is negative
  1219. */
  1220. if(fabs(temp) >= 10.)
  1221.      {
  1222.        while(fabs(temp) >= 10.)
  1223.           {
  1224.               evalue = evalue + 1;
  1225.           temp = temp / 10.;
  1226.           }
  1227.         }
  1228. else if(fabs(temp) < 1.)
  1229.     {
  1230.         while(fabs(temp) < 1.)
  1231.           {
  1232.             evalue = evalue - 1;
  1233.           temp = temp * 10.;
  1234.           }
  1235.     }
  1236. /*
  1237. Extract out the fractional portion of the real value
  1238. */
  1239. exp = (long int) r4;
  1240. realexp =  (float) exp;
  1241. rfrac = r4-realexp;
  1242. /*
  1243. Convert significant digits of fraction portion to integer by multiplying.
  1244. */
  1245. base = 10.;
  1246. power = (double) (6-evalue);
  1247. x = rfrac*pow(base,power);
  1248. if(x > 0.)
  1249.    frac = (long int) (x + .5);
  1250. else
  1251.    frac = (long int) (x - .5);
  1252. fracr8 = (double) frac;
  1253. r4r8 = (double) exp;
  1254. /*
  1255. Convert the integer back into a fraction by diving.
  1256. then ADD back in the integer portion.
  1257. */
  1258. r4r8 = r4r8 + fracr8/(pow(base, power));
  1259. return(r4r8);
  1260. }
  1261. long int CDFWALK_get_index(CDF_id, dim_num, var_num, value, data_type,
  1262.                 dim_values, num_values)
  1263. long int        CDF_id;
  1264. long int        dim_num;
  1265. long int        var_num;
  1266. long int        data_type;
  1267. double            value;
  1268. double            dim_values[];
  1269. long int        num_values;
  1270. {
  1271. long int        i;
  1272. double            diff,closest_diff;
  1273. long int        closest_indice;
  1274. double            min,max,fudge_up,fudge_down;
  1275. long int        indices[10];
  1276. long int        record_num;
  1277. CDFstatus        rcode;
  1278. double            test_value;
  1279. union     mixed         temp;
  1280. double            r4_r8();
  1281.  
  1282.  
  1283. if(data_type != CDF_REAL8 && data_type != CDF_EPOCH)
  1284.    {
  1285.    fudge_down = .999999; fudge_up = 1.000001;
  1286.    if(value > 0.)
  1287.       {
  1288.       min = fudge_down*value;
  1289.       max = fudge_up*value;
  1290.       }
  1291.    else
  1292.       {
  1293.       min = fudge_up*value;
  1294.       max = fudge_down*value;
  1295.       }
  1296.    }
  1297. else
  1298.    {
  1299.    min = value;
  1300.    max = value;
  1301.    }
  1302. if(num_values > MAX_VALUES)
  1303.    {
  1304.    record_num = 0;
  1305.    for (i=0; i < CDF_MAX_DIMS; i++)
  1306.      indices[i] = 0;
  1307.    }
  1308. closest_diff = 1.7e38;
  1309. closest_indice = 0;
  1310. for(i=0; i<num_values; i++)
  1311.     {
  1312.     if(num_values > MAX_VALUES)
  1313.        {
  1314.        if(dim_num > 0)
  1315.       indices[dim_num-1]=i;
  1316.        else
  1317.       record_num = i;
  1318.        switch(data_type)
  1319.           {
  1320.           case CDF_REAL4:
  1321.           case CDF_FLOAT:
  1322.            rcode = CDFvarGet(CDF_id, var_num, record_num,
  1323.                indices, &temp.r4);
  1324.            test_value = r4_r8(&temp.r4);
  1325.            break;
  1326.           case CDF_REAL8:
  1327.           case CDF_DOUBLE:
  1328.           case CDF_EPOCH:
  1329.            rcode = CDFvarGet(CDF_id, var_num, record_num,
  1330.                indices, &temp.r8);
  1331.            test_value = temp.r8;
  1332.            break;
  1333.           case CDF_INT4:
  1334.            rcode = CDFvarGet(CDF_id, var_num, record_num,
  1335.            indices, &temp.i4);
  1336.            test_value = (double) temp.i4;
  1337.            break;
  1338.           case CDF_UINT4:
  1339.            rcode = CDFvarGet(CDF_id, var_num, record_num,
  1340.                indices, &temp.ui4);
  1341.            test_value = (double) temp.ui4;
  1342.            break;
  1343.           case CDF_INT2:
  1344.            rcode = CDFvarGet(CDF_id, var_num, record_num,
  1345.                indices, &temp.i2);
  1346.            test_value = (double) temp.i2;
  1347.            break;
  1348.           case CDF_UINT2:
  1349.            rcode = CDFvarGet(CDF_id, var_num, record_num,
  1350.                indices, &temp.ui2);
  1351.            test_value = (double) temp.ui2;
  1352.            break;
  1353.           case CDF_BYTE:
  1354.           case CDF_INT1:
  1355.            rcode = CDFvarGet(CDF_id, var_num, record_num,
  1356.                indices, &temp.byte);
  1357.            test_value = (double) temp.byte;
  1358.            break;
  1359.           case CDF_UINT1:
  1360.            rcode = CDFvarGet(CDF_id, var_num, record_num,
  1361.                indices, &temp.ubyte);
  1362.            test_value = (double) temp.ubyte;
  1363.           }
  1364.       if(rcode < CDF_OK)test_value = 1.7e38;
  1365.        }
  1366.     else
  1367.     test_value = dim_values[i];
  1368.     if(test_value >= min && test_value <= max)return(i);
  1369.     diff = fabs(test_value - value);
  1370.     if(diff < closest_diff)
  1371.        {
  1372.        closest_diff = diff;
  1373.        closest_indice = i;
  1374.        }
  1375.     }
  1376. return(closest_indice);
  1377. }
  1378. long int CDFWALK_get_index_char(CDF_id, dim_num, var_num, value,
  1379.                 num_bytes, dim_values, num_values)
  1380. long int        CDF_id;
  1381. long int        dim_num;
  1382. long int        var_num;
  1383. char            *value;
  1384. long int        num_bytes;
  1385. char            dim_values[];
  1386. long int        num_values;
  1387. {
  1388. long int        i;
  1389. long int        closest_indice;
  1390. long int        most;
  1391. long int        num;
  1392. long int        indices[CDF_MAX_DIMS];
  1393. long int        record_num;
  1394. CDFstatus        rcode;
  1395. char            *string;
  1396.  
  1397. closest_indice = 0;
  1398. most = 0;
  1399.  
  1400. string = (char *) malloc(num_bytes+1);
  1401. if(string == NULL)return(closest_indice);
  1402. if(num_values > MAX_VALUES)
  1403.    {
  1404.    record_num = 0;
  1405.    for (i=0; i < CDF_MAX_DIMS; i++)
  1406.      indices[i] = 0;
  1407.    }
  1408.  
  1409.  
  1410. for(i=0; i<num_values; i++)
  1411.     {
  1412.     if(num_values > MAX_VALUES)
  1413.        {
  1414.        if(dim_num > 0)
  1415.       indices[dim_num-1]=i;
  1416.        else
  1417.       record_num = i;
  1418.  
  1419.        rcode = CDFvarGet(CDF_id, var_num, record_num, indices,
  1420.         string);
  1421.        if(rcode < CDF_OK)
  1422.       string[0] = '\0';
  1423.        else
  1424.       string[num_bytes] = '\0';
  1425.        }
  1426.     else
  1427.        strcpy( string, &dim_values[i*(num_bytes+1)]);
  1428.     num = how_many_match(value, string);
  1429.     if(num > most)
  1430.        {
  1431.        closest_indice = i;
  1432.        most = num;
  1433.        }
  1434.     }
  1435. free(string);
  1436. return(closest_indice);
  1437. }
  1438. void make_it_upper(upstring,string)
  1439. char    *upstring;
  1440. char    *string;
  1441. {
  1442. int    i,len;
  1443. len=strlen(string);
  1444. for(i=0; i<len; i++)
  1445.     {
  1446.     upstring[i] = (islower(string[i]) ?
  1447.             toupper(string[i]) : string[i]);
  1448.     }
  1449. }
  1450. long int how_many_match(str1, str2)
  1451. char        *str1;
  1452. char        *str2;
  1453. {
  1454. char        *up1, *up2;
  1455. long int    num,i;
  1456. up1 = (char *) malloc(strlen(str1) + 1);
  1457. up2 = (char *) malloc(strlen(str2) + 1);
  1458. make_it_upper(up1, str1);
  1459. make_it_upper(up2, str2);
  1460. for(i=0, num=0; up1[i] == up2[i] && up1[i] != '\0'; i++)
  1461.     num++;
  1462. free(up1);
  1463. free(up2);
  1464. return(num);
  1465. }
  1466. long int     check_epoch(str, scale)
  1467. char        str[];
  1468. double        *scale;
  1469. {
  1470. static char    default_time[] = " 00:00:00.000";
  1471. long int    len;
  1472. long int    rcode;
  1473. *scale = 0.;
  1474. len = strlen(str);
  1475. if(len == 0)
  1476.    return(TRUE);
  1477. else if(len < 11)
  1478.         return(FALSE);
  1479. else if(len < 24)
  1480.     strcat(str, default_time+(len+2-13));
  1481. rcode = epochParse(str, &ep);
  1482. *scale = ep.tSince0;
  1483. return(rcode);
  1484. }
  1485. void CDFWALK_free_discrete(variables, num_vars)
  1486. struct variable_struct        variables[];
  1487. long int            num_vars;
  1488. {
  1489. long int            var_num;
  1490. for(var_num = 0; var_num < num_vars; var_num++)
  1491.     {
  1492.     if(V.bin_value != NULL)free(V.bin_value);
  1493.     if(V.char_value != NULL)free(V.char_value);
  1494.     }
  1495. }
  1496.  
  1497.